home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
text
/
show
/
jmore03.lzh
/
jmoresrc.LZH
/
jmore.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-05
|
12KB
|
594 lines
/*
* jmore.c
* H.Ohkubo Oct. 4, 1992
*
* Modified Oct. 17, 1992 (Ver.0.02)
* Modified 0ct. 22, 1992 (Ver.0.03)
*/
#include <exec/types.h>
#include <exec/ports.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <workbench/startup.h>
#include <functions.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include "jctype.h"
#include "openlib.h"
#include "jFont.h"
#include "jmore.h"
struct Screen *Scrn = NULL;
struct Window *Wind = NULL;
struct RastPort *rport = NULL;
int current_x, current_y;
/* for backcscroll */
USHORT current_line, top_line;
SHORT count[USHRT_MAX];
FILE *infile = NULL;
char in_fname[FNAMELEN];
struct TextFont *current_font = NULL;
struct TextFont *resident_font[KATA + 1];
BPTR olddir = NULL;
int tabspc = TABSPC;
BOOL regular = FALSE;
struct MsgPort *jMorePort = NULL;
struct jFontMsg fontMsg;
/* prototypes */
VOID print_file(VOID);
int print_file_doit(VOID);
VOID handle_ank_code(char *);
VOID handle_kanji_code(char *);
VOID handle_ctrl_code(int);
char *strchr_r(char *, int);
int keyin_loop(LONG *, int, char *);
int print_message(char *);
int handle_rawkey(VOID);
int count_bytes(LONG *, int);
VOID fseek_back(int);
VOID init_myMsg(VOID);
struct MsgPort *init_myport(VOID);
struct TextFont *get_font(USHORT);
struct TextFont *init_resident_font(VOID);
VOID OpenScrnWind(VOID);
FILE *fset(char *, char *);
VOID clean_exit(char *, int);
VOID usage(VOID);
VOID get_startup(VOID);
int set_startup_value(FILE *);
char *my_getline(FILE *);
VOID main(int argc, char *argv[])
{
if (argc == 0) {
struct WBStartup *argmsg = (struct WBStartup *)argv;
struct WBArg *wb_arg = argmsg->sm_ArgList;
if (argmsg->sm_NumArgs < 2)
exit(EXIT_FAILURE);
if (wb_arg[1].wa_Lock != NULL)
olddir = CurrentDir(wb_arg[1].wa_Lock);
strcpy(in_fname, wb_arg[1].wa_Name);
}
else {
if (argc < 2)
usage();
puts(COPYRIGHT);
strcpy(in_fname, argv[1]);
}
infile = (FILE *)fset(in_fname, READ_BINARY);
get_startup();
init_myMsg();
if (!OpenLib())
clean_exit("No Library !", RETURN_FAIL);
OpenScrnWind(); /* initialize jmore's screen */
print_file();
clean_exit(END_MESSAGE, RETURN_OK);
}
#define tabwidth(w) (tabspc*(w))
#define tabalign(x, w) (((x)/tabwidth(w))*tabwidth(w) + tabwidth(w))
char pool[BUFFSIZE + 1];
char strbuff[STRBUFSIZE];
VOID print_file(VOID)
{
current_font = init_resident_font();
SetFont(rport, current_font);
SetAPen(rport, 1);
SetDrMd(rport, JAM2);
current_x = Wind->BorderLeft;
current_y = Wind->BorderTop + rport->TxBaseline;
Move(rport, current_x, current_y);
current_line = top_line = 0;
count[current_line] = 0;
while (print_file_doit())
;
}
int print_file_doit(VOID)
{
int len, remaining_size = 0, n;
char *buff, *buff_tail, *head, *next_head, *p;
#if 0
char *line_head, *line_tail;
#endif
pool[0] = pool[BUFFSIZE] = LF;
buff = pool + 1;
buff_tail = pool + BUFFSIZE;
head = buff;
while ((len = fread(head, sizeof(char), buff_tail - head, infile)) > 0) {
next_head = strchr_r(head + len - 1, LF) + 1;
p = buff;
while (p < next_head) {
count[current_line]++;
switch (nthmsctype(buff, p - buff)) {
case CT_KJ2:
handle_kanji_code(p);
break;
case CT_KJ1:
break;
case CT_ANK:
handle_ank_code(p);
break;
case CT_ILGL:
default:
handle_ctrl_code((int)(*p));
break;
}
p++;
if (current_y > (Wind->Height - FONT_SIZE)) {
switch (n = keyin_loop((VOID *)&p, p - buff, MORE_MES)) {
case QUIT:
return FALSE;
break;
case NORMAL:
break;
default: /* back scroll */
fseek_back(len + remaining_size + n);
return TRUE;
break;
}
}
}
remaining_size = len - (next_head - head);
memmove(buff, next_head, remaining_size);
head = buff + remaining_size;
}
if ((n = keyin_loop((VOID *)&buff, 0, FILE_END_MES)) > 0) {
fseek_back(len + remaining_size + n);
return TRUE;
}
return FALSE;
}
VOID handle_ank_code(char *code)
{
if (current_font != resident_font[ANK]) {
Text(rport, strbuff, strlen(strbuff));
strbuff[0] = NUL;
current_font = resident_font[ANK];
SetFont(rport, current_font);
current_x = rport->cp_x;
}
if ((current_x += current_font->tf_XSize) >= Wind->Width)
handle_ctrl_code(LF);
strncat(strbuff, code, sizeof(char));
}
VOID handle_kanji_code(char *p)
{
USHORT kanji;
int fontnum;
char code;
struct TextFont *tf;
kanji = (*(p - 1)&0xff)<<CHAR_BIT | *p&0xff;
kanji = mstojis(kanji);
fontnum = ((kanji>>CHAR_BIT)&0xff) - SPC;
code = (char)(kanji&0xff);
if (fontnum >= SYM1 && fontnum <= KATA) {
if (regular && (isjalnum(kanji) || isjsymbol(kanji))) {
int ascii_code;
if ((ascii_code = jistoascii(kanji))) {
tf = resident_font[ANK];
code = (char)ascii_code;
}
else
tf = resident_font[fontnum];
}
else
tf = resident_font[fontnum];
}
else {
if ((tf = get_font(kanji)) == NULL) {
tf = resident_font[SYM1];
code = KNJ_ILGL;
}
}
if (current_font != tf) {
Text(rport, strbuff, strlen(strbuff));
strbuff[0] = NUL;
current_font = tf;
SetFont(rport, current_font);
current_x = rport->cp_x;
}
if ((current_x += current_font->tf_XSize) >= Wind->Width)
handle_ctrl_code(LF);
strncat(strbuff, &code, sizeof(char));
}
VOID handle_ctrl_code(int code)
{
Text(rport, strbuff, strlen(strbuff));
strbuff[0] = NUL;
switch (code) {
case LF:
current_x = Wind->BorderLeft;
current_y += FONT_SIZE;
Move(rport, current_x, current_y);
count[++current_line] = 0;
break;
case TAB:
current_x = tabalign(rport->cp_x, resident_font[ANK]->tf_XSize);
Move(rport, current_x, current_y);
break;
default:
break;
}
}
char *strchr_r(char *str, int c)
{
while (*str != c)
str--;
return str;
}
#define forward_scroll(rport) (ScrollRaster((rport), 0, FONT_SIZE, \
Wind->BorderLeft, Wind->BorderTop, \
Wind->Width, Wind->Height - FONT_SIZE - 1))
#define backward_scroll(rport) (ScrollRaster((rport), 0, -FONT_SIZE, \
Wind->BorderLeft, Wind->BorderTop, \
Wind->Width, Wind->Height - FONT_SIZE - 1))
#define clear_screen(rport) (SetRast((rport), 0))
int keyin_loop(LONG *point, int nbyte, char *mes)
{
int retval = NORMAL;
switch (print_message(mes)) {
case QUIT_PRG:
retval = QUIT;
break;
case LINE_SCROLL:
current_y -= FONT_SIZE;
Move(rport, current_x, current_y);
forward_scroll(rport);
top_line++;
break;
case BACK_LINE:
current_y = Wind->BorderTop + rport->TxBaseline;
Move(rport, current_x, current_y);
if (top_line > 0) {
backward_scroll(rport);
top_line--;
}
retval = count_bytes(point, nbyte);
break;
case BACK_SCROLL:
current_y = Wind->BorderTop + rport->TxBaseline;
Move(rport, current_x, current_y);
clear_screen(rport);
top_line = (top_line > TOTAL_LINES) ?
top_line - TOTAL_LINES : 0;
retval = count_bytes(point, nbyte);
break;
case PAGE_SCROLL:
default:
current_y = Wind->BorderTop + rport->TxBaseline;
Move(rport, current_x, current_y);
clear_screen(rport);
top_line = current_line;
break;
}
return retval;
}
int print_message(char *mes)
{
struct TextFont *tf = current_font;
int x, y;
char strbuf[STRBUFSIZE];
x = Wind->BorderLeft;
y = Wind->Height - FONT_SIZE + rport->TxBaseline;
Move(rport, x, y);
current_font = resident_font[ANK];
SetFont(rport, current_font);
sprintf(strbuf, mes, in_fname);
SetDrMd(rport, JAM2|INVERSVID);
Text(rport, strbuf, strlen(strbuf));
SetDrMd(rport, JAM2);
current_font = tf;
SetFont(rport, current_font);
return handle_rawkey();
}
int handle_rawkey(VOID)
{
BOOL done = FALSE;
int retval;
struct IntuiMessage *msg;
while (!done) {
WaitPort(Wind->UserPort);
while (msg = (struct IntuiMessage *)GetMsg(Wind->UserPort)) {
ReplyMsg((struct Message *)msg);
switch (msg->Class) {
case RAWKEY:
switch (msg->Code) {
case QUIT_PRG:
case LINE_SCROLL:
case BACK_LINE:
case PAGE_SCROLL:
case BACK_SCROLL:
retval = msg->Code;
done = TRUE;
default:
break;
}
break;
default:
break;
}
}
}
return retval;
}
int count_bytes(LONG *point, int nbyte)
{
int sum = 0;
do {
sum += count[--current_line];
} while (current_line != top_line);
count[current_line] = 0;
if (sum > nbyte)
return sum - nbyte;
else {
*point -= sum;
return NORMAL;
}
}
VOID fseek_back(int nbyte)
{
if (fseek(infile, -nbyte, SEEK_CUR) != 0)
clean_exit("fseek error !", RETURN_FAIL);
}
/* initialize the jFontMsg structure */
VOID init_myMsg(VOID)
{
struct jFontMsg *msg = &fontMsg;
msg->msg.mn_Node.ln_Type = NT_MESSAGE;
msg->msg.mn_Length = sizeof(struct jFontMsg);
msg->msg.mn_ReplyPort = init_myport();
}
/* initialize the MsgPort for ReplyMsg */
struct MsgPort *init_myport(VOID)
{
if (FindPort(JMOREPORT) == NULL) {
if ((jMorePort = CreatePort(JMOREPORT, NORMAL_PRI)) != NULL)
return jMorePort;
}
clean_exit("jMore is already used.", RETURN_FAIL);
return (struct MsgPort *)NULL; /* but not reached here */
}
struct TextFont *get_font(USHORT kanji)
{
struct MsgPort *mPort;
struct jFontMsg *msg = &fontMsg;
msg->kanji = kanji;
Forbid();
if ((mPort = FindPort(JFONTPORT)) == NULL)
clean_exit("jFontSys is not installed !", RETURN_FAIL);
PutMsg(mPort, (struct Message *)msg);
Permit();
WaitPort(jMorePort);
msg = (struct jFontMsg *)GetMsg(jMorePort);
return msg->font;
}
struct TextFont *init_resident_font(VOID)
{
int i;
for (i = SYM1; i <= KATA; i++)
resident_font[i] = get_font((USHORT)((i + ' ')<<CHAR_BIT));
return (resident_font[ANK] = get_font((USHORT)ANK_FONT_CODE));
}
/* ScrnDefn & WindDefn is declere in jmore.h */
VOID OpenScrnWind(VOID)
{
if ((Scrn = (struct Screen *)OpenScreen(&ScrnDefn)) == NULL)
clean_exit("No Screen !", RETURN_FAIL);
ShowTitle(Scrn, FALSE);
WindDefn.Screen = Scrn;
if ((Wind = (struct Window *)OpenWindow(&WindDefn)) == NULL)
clean_exit("No Window !", RETURN_FAIL);
rport = Wind->RPort;
}
FILE *fset(char *fname, char *mode)
{
FILE *fp;
if ((fp = fopen(fname, mode)) == NULL)
clean_exit(strcat(fname, " not open !"), RETURN_FAIL);
return fp;
}
VOID clean_exit(char *mes, int extval)
{
if (Wind)
CloseWindow(Wind);
if (Scrn)
CloseScreen(Scrn);
CloseLib();
if (jMorePort)
DeletePort(jMorePort);
if (infile)
fclose(infile);
if (olddir)
CurrentDir(olddir);
if (*mes)
fprintf(stderr, "%s\n", mes);
exit(extval);
}
VOID usage(VOID)
{
puts(ERROR_MESSAGE);
exit(EXIT_FAILURE);
}
/* for startup file routine */
VOID get_startup(VOID)
{
FILE *fp;
if ((fp = fopen(STARTUP, READ_BINARY)) != NULL) {
while (set_startup_value(fp) != EOF)
;
fclose(fp);
}
}
int set_startup_value(FILE *fp)
{
char *lp, *name_end, *value_head;
int c;
lp = my_getline(fp);
if ((name_end = strchr(lp, '=')) != NULL) {
value_head = name_end + 1;
if (strncmp(startup[TAB_WIDTH], lp, name_end - lp) == 0) {
tabspc = atoi(value_head);
}
}
else if (strlen(lp) > 0) {
if (strcmp(startup[REGULAR], lp) == 0) {
regular = TRUE;
}
}
c = fgetc(fp);
ungetc(c, fp); /* for check EOF */
return c;
}
#define LINEBUFLEN 80
char *my_getline(FILE *fp)
{
int c, iscomment = FALSE;
static char linebuf[LINEBUFLEN], *lp;
lp = linebuf;
while ((c = fgetc(fp)) != LF && c != EOF) {
if (!iscomment && isgraph(c)) {
switch (c) {
case COMMENT_MARK:
iscomment = TRUE;
break;
default:
if (islower(c))
c = toupper(c);
*lp++ = (char)c;
break;
}
}
}
*lp = NUL;
return linebuf;
}